package com.kate.mall.oauth.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.kate.mall.common.utils.R;
import com.kate.mall.oauth.constant.AuthConstants;
import com.kate.mall.oauth.constant.MessageConstant;
import com.kate.mall.oauth.dto.Oauth2TokenDto;
import com.nimbusds.jose.JWSObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.text.ParseException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 用一句话描述
 * @Auther: 新梦想*陈超
 * @Date: 2021/8/24 14:30
 * http://localhost:8888/wx/auth/login_by_weixin
 */
@RestController
@RequestMapping("/oauth")
@Slf4j
public class AuthController {

    @Resource
    private TokenEndpoint tokenEndpoint;
    /**
     * Oauth2登录认证
     */
    @PostMapping(value = "/token")
    public R postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.builder()
                .token(oAuth2AccessToken.getValue())
                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
                .expiresIn(oAuth2AccessToken.getExpiresIn())
                .tokenHead("Bearer ").build();  //"Bearer xxx"

        return  R.ok().put("data",oauth2TokenDto);
    }
    @Resource
    private RedisTemplate redisTemplate;

    @DeleteMapping("/logout")
    public R logout(HttpServletRequest request) throws ParseException {
        String token = request.getHeader("Authorization");
        log.info("logout ，current token is :{}",token);

        token = token.replace("Bearer", Strings.EMPTY);
        JWSObject jwsObject = JWSObject.parse(token);
        String payload = jwsObject.getPayload().toString();


        JSONObject jsonObject = JSONUtil.parseObj(payload);
        String jti = jsonObject.getStr("jti"); // JWT唯一标识
        long exp = jsonObject.getLong("exp"); // JWT过期时间戳(单位:秒)

        long currentTimeSeconds = System.currentTimeMillis() / 1000;

        if (exp < currentTimeSeconds) { // token已过期
            return R.error(MessageConstant.CREDENTIALS_EXPIRED);
        }
        redisTemplate.opsForValue().set(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti, null, (exp - currentTimeSeconds), TimeUnit.SECONDS);
        return R.ok("退出成功");
    }
}
